/*
 *  BLAuthentication.m
 *  FireWall
 *
 *  Created by Admin on 8/01/13.
 *  Copyright (c) 2013 Admin. All rights reserved.
 *
 */
#import "BLAuthentication.h"
#import <Security/AuthorizationTags.h>

static BLAuthentication *sharedObject = nil;

@implementation BLAuthentication

+ (id)shared
{
    if (!sharedObject) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedObject = [[self alloc] init];
        });
    }
    
    return sharedObject;
}

- (BOOL)isAuthenticated:(NSString *)forCommand {	
	AuthorizationItem items[1];
	AuthorizationRights rights;
	AuthorizationRights *authorizedRights;
	AuthorizationFlags flags;
	
	OSStatus err = 0;
	BOOL authorized = NO;
	
	
	if(_authorizationRef == NULL)
    {
		rights.count = 0;
		rights.items = NULL;
		
		flags = kAuthorizationFlagDefaults;
		err = AuthorizationCreate(&rights, kAuthorizationEmptyEnvironment, flags, &_authorizationRef);
	}
	
	char *command = malloc(sizeof(char) * 1024);
	[forCommand getCString:command maxLength:1024];
	items[0].name = kAuthorizationRightExecute;
	items[0].value = command;
	items[0].valueLength = strlen(command);
	items[0].flags = 0;
	
    rights.count = 1;
    rights.items = items;
    
    flags = kAuthorizationFlagExtendRights;
    
    err = AuthorizationCopyRights(_authorizationRef, &rights, kAuthorizationEmptyEnvironment, flags, &authorizedRights);
	
    authorized = (errAuthorizationSuccess == err);
	
	if(authorized)
    {
		AuthorizationFreeItemSet(authorizedRights);
	}
	
    return authorized;
}

- (BOOL)fetchPassword:(NSString *)forCommand {
	AuthorizationItem items[1];
	AuthorizationRights rights;
	AuthorizationRights *authorizedRights;
	AuthorizationFlags flags;
	
	OSStatus err = 0;
	BOOL authorized = NO;
	
	
	if(_authorizationRef == NULL) {
		rights.count = 0;
		rights.items = NULL;
		
		flags = kAuthorizationFlagDefaults;
		err = AuthorizationCreate(&rights, kAuthorizationEmptyEnvironment, flags, &_authorizationRef);
	}
	
	char *command = malloc(sizeof(char) * 1024);
	[forCommand getCString:command maxLength:1024];
	items[0].name = kAuthorizationRightExecute;
	items[0].value = command;
	items[0].valueLength = strlen(command);
	items[0].flags = 0;
	
    rights.count = 1;
    rights.items = items;
    
	flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;
	
	err = AuthorizationCopyRights(_authorizationRef, &rights, kAuthorizationEmptyEnvironment, flags, &authorizedRights);
	
	authorized = (errAuthorizationSuccess == err);
	
	if(authorized)
    {
		AuthorizationFreeItemSet(authorizedRights);
	}                                                    
	
	return authorized;
}

- (BOOL)authenticate:(NSString *)forCommand {
	if( ![self isAuthenticated:forCommand] )
    {
        [self fetchPassword:forCommand];
	}
	
	return [self isAuthenticated:forCommand];
}

-(BOOL)executeCommand:(NSString *)pathToCommand withArgs:(NSArray *)arguments
{
	char* args[30];
	OSStatus err = 0;
	unsigned int i = 0;
	
	if(![self authenticate:pathToCommand])
    {
		return NO;
    }
	
	if( arguments == nil || [arguments count] < 1 )
    {
		err = AuthorizationExecuteWithPrivileges(_authorizationRef, [pathToCommand fileSystemRepresentation], 0, NULL, NULL);       // old
	}
	else
    {
		while( i < [arguments count] && i < 19)
        {
			args[i] = (char*)[[arguments objectAtIndex:i] cString];
			i++;
		}
		args[i] = NULL;
		
		err = AuthorizationExecuteWithPrivileges(_authorizationRef, [pathToCommand fileSystemRepresentation], 0, args, NULL);           // old
	}
	
	if(err != 0)
    {
		NSLog(@"Error %ld in AuthorizationExecuteWithPrivileges",err);
		return NO;
	}
	else
    {
		return YES;
	}
}

@end
